/*
 * <h3>Title:wheel-utils系统</h3>
 * <p>Copyright (c) 2019, wnfbx@163.com. All rights reserved.</p>
 * @author wnfbx@163.com
 */
package wang.naifei.core.utils;

import java.io.Writer;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.List;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * <dt>Description:StringUtils</dt>
 * <dd>文件工具类</dd>
 * <dd>author: wnfbx@163.com</dd>
 * <dd>version:1.0 <i>2022/1/14 23:48</i></dd>
 *
 * @since jdk1.7+
 */
public class StringUtils extends org.springframework.util.StringUtils {

    /**
     * <dt>Description:lineSeparator</dt>
     * <dd>换行符</dd>
     * <dd>author: wnfbx@163.com</dd>
     * <dd>version:1.0 <i>2022/1/16 19:28</i></dd>
     *
     * @see java.io.BufferedWriter#BufferedWriter(Writer, int) 中的lineSeparator赋值
     * @since jdk1.8
     */
    public static String lineSeparator = java.security.AccessController.doPrivileged(new sun.security.action.GetPropertyAction("line.separator"));

    /**
     * <dt>Description:toBoolean</dt>
     * <dd>类似js的布尔转换<p>如果是字符 只有n no 0 false是假其他都是真 如果是数字大于0的都是真 如果是对象不为空即是真</p></dd>
     * <dd>author: wnfbx@163.com</dd>
     * <dd>version:1.0 <i>2022/1/15 15:24</i></dd>
     *
     * @param o 目标对象
     * @return java.lang.Boolean
     * @since jdk1.7+
     */
    public static Boolean toBoolean(Object o) {
        boolean r = false;
        if (o != null) {
            r = true;
            if ((o instanceof String)) {
                String tmp = (String) o;
                if ("n".equalsIgnoreCase(tmp))
                    r = false;
                else if ("no".equals(tmp))
                    r = false;
                else if ("0".equals(tmp))
                    r = false;
                else if ("false".equalsIgnoreCase(tmp.toLowerCase())) {
                    r = false;
                }
            }
            if ((o instanceof Integer)) {
                int tmp = ((Integer) o).intValue();
                if (tmp <= 0) {
                    r = false;
                }
            }
            if (o instanceof Boolean) {
                r = (Boolean) o;
            }
        }
        return Boolean.valueOf(r);
    }

    /**
     * <dt>Description:isNotEmpty</dt>
     * <dd>扩展spring的isEmpty方法</dd>
     * <dd>author: wnfbx@163.com</dd>
     * <dd>version:1.0 <i>2022/1/15 15:25</i></dd>
     *
     * @param o 目标对象
     * @return boolean
     * @since jdk1.7+
     */
    public static boolean isNotEmpty(Object o) {
        return !isEmpty(o);
    }

    /**
     * <dt>Description:isRealEmpty</dt>
     * <dd>扩展spring的isEmpty方法</dd>
     * <dd>author: wnfbx@163.com</dd>
     * <dd>version:1.0 <i>2022/1/15 15:26</i></dd>
     *
     * @param o 目标对象
     * @return java.lang.Boolean
     * @since jdk1.7+
     */
    public static Boolean isRealEmpty(Object o) {
        boolean r = isEmpty(o);
        if (!r) {
            if ((o instanceof String))
                r = ((String) o).trim().length() == 0;
            else if ((o instanceof List))
                r = ((List<?>) o).isEmpty();
            else
                throw new RuntimeException("对象类型不识别 不能判断");
        }
        return r;
    }

    /**
     * <dt>Description:isNotRealEmpty</dt>
     * <dd>扩展isRealEmpty方法</dd>
     * <dd>author: wnfbx@163.com</dd>
     * <dd>version:1.0 <i>2022/1/15 15:26</i></dd>
     *
     * @param o 目标对象
     * @return java.lang.Boolean
     * @since jdk1.7+
     */
    public static Boolean isNotRealEmpty(Object o) {
        return !isRealEmpty(o);
    }

    /**
     * <dt>Description:isBlank</dt>
     * <dd>为blank</dd>
     * <dd>author: wnfbx@163.com</dd>
     * <dd>version:1.0 <i>2022/1/15 15:45</i></dd>
     *
     * @param s 字符串
     * @return java.lang.Boolean
     * @since jdk1.7+
     */
    public static Boolean isBlank(String s) {
        return isEmpty(s.trim());
    }

    /**
     * <dt>Description:isNotBlank</dt>
     * <dd>非blank</dd>
     * <dd>author: wnfbx@163.com</dd>
     * <dd>version:1.0 <i>2022/1/15 15:46</i></dd>
     *
     * @param s 字符串
     * @return java.lang.Boolean
     * @since jdk1.7+
     */
    public static Boolean isNotBlank(String s) {
        return !isNotEmpty(s);
    }

    /**
     * <dt>Description:getRandomString</dt>
     * <dd>根据字符生成随机字符串 利用random区分大小写</dd>
     * <dd>author: wnfbx@163.com</dd>
     * <dd>version:1.0 <i>2022/1/15 15:48</i></dd>
     *
     * @param length  随机字符串长度
     * @param allChar 生成字符串的字符范围
     * @return java.lang.String
     * @since jdk1.7+
     */
    public static String getRandomString(int length, String allChar) {
        StringBuilder sb = new StringBuilder();
        Random random = new Random();
        for (int i = 0; i < length; i++) {
            sb.append(allChar.charAt(random.nextInt(allChar.length())));
        }
        return sb.toString();
    }

    /**
     * <dt>Description:getRandomString</dt>
     * <dd>根据字母和数字生成随机字符串</dd>
     * <dd>author: wnfbx@163.com</dd>
     * <dd>version:1.0 <i>2022/1/15 15:49</i></dd>
     *
     * @param length 生成字符串长度
     * @return java.lang.String
     * @since jdk1.7+
     */
    public static String getRandomString(int length) {
        String allChar = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
        return getRandomString(length, allChar);
    }

    /**
     * <dt>Description:NVL</dt>
     * <dd>null值转空</dd>
     * <dd>author: wnfbx@163.com</dd>
     * <dd>version:1.0 <i>2022/1/15 15:50</i></dd>
     *
     * @param o 值
     * @return java.lang.String
     * @since jdk1.7+
     */
    public static String NVL(Object o) {
        return o == null ? "" : o.toString();
    }

    /**
     * <dt>Description:EVL</dt>
     * <dd>空、零、null字符转空</dd>
     * <dd>author: wnfbx@163.com</dd>
     * <dd>version:1.0 <i>2022/1/15 15:50</i></dd>
     *
     * @param o 值
     * @return java.lang.String
     * @since jdk1.7+
     */
    public static String EVL(Object o) {
        String nvl = NVL(o);
        return ("0".equals(nvl)) || ("null".equals(nvl)) ? "" : nvl;
    }

    /**
     * <dt>Description:stringNumbers</dt>
     * <dd>字符串包含字符串的数量，sql查询参数等用</dd>
     * <dd>author: wnfbx@163.com</dd>
     * <dd>version:1.0 <i>2022/1/15 16:00</i></dd>
     *
     * @param str 目标字符串
     * @param c   被包含字符串
     * @return int
     * @since jdk1.7+
     */
    public static int stringNumbers(String str, String c) {
        int i = str.indexOf(c);
        int counter = 0;
        while (i != -1) {
            counter++;
            i = str.indexOf(c, i + 1);
        }
        return counter;
    }

    /**
     * <dt>Description:toHtmlString</dt>
     * <dd>表单string转html</dd>
     * <dd>author: wnfbx@163.com</dd>
     * <dd>version:1.0 <i>2022/1/15 16:01</i></dd>
     *
     * @param s html字符
     * @return java.lang.String
     * @since jdk1.7+
     */
    public static String toHtmlString(String s) {
        if (s != null) {
            s = s.replace(" ", "&#160;");
        }
        return s;
    }

//	/**
//	 * 类似js的join
//	 *
//	 * @param array
//	 * @return
//	 */
//	public static String join(Object[] array) {
//		return org.apache.commons.lang.StringUtils.join(array);
//	}
//
//	/**
//	 * 类似js的join
//	 *
//	 * @param array
//	 * @return
//	 */
//	public static String join(Object[] array, String separator) {
//		return org.apache.commons.lang.StringUtils.join(array, separator);
//	}
//
//	/**
//	 * 类似js的join
//	 *
//	 * @param array
//	 * @return
//	 */
//	public static String join(Collection<?> collection, String separator) {
//		return org.apache.commons.lang.StringUtils.join(collection, separator);
//	}
//
//	/**
//	 * 类似js的join
//	 *
//	 * @param array
//	 * @return
//	 */
//	public static String join(Object[] array, char separator) {
//		return org.apache.commons.lang.StringUtils.join(array, separator);
//	}
//
//	/**
//	 * 类似js的join
//	 *
//	 * @param array
//	 * @return
//	 */
//	public static String join(Collection<?> collection, char separator) {
//		return org.apache.commons.lang.StringUtils.join(collection, separator);
//	}


    /**
     * <dt>Description:byteToHexString</dt>
     * <dd>byte转16进制</dd>
     * <dd>author: wnfbx@163.com</dd>
     * <dd>version:1.0 <i>2022/1/15 16:03</i></dd>
     *
     * @param data byte数据
     * @return java.lang.String
     * @since jdk1.7+
     */
    public static String toHex(byte[] data) {
        StringBuilder strBuffer = new StringBuilder();
        for (byte datum : data) {
            strBuffer.append(Integer.toHexString(0xff & datum));
        }
        return strBuffer.toString();
    }

    /**
     * <dt>Description:getMd5MessageDigest</dt>
     * <dd>md5签名</dd>
     * <dd>author: wnfbx@163.com</dd>
     * <dd>version:1.0 <i>2022/1/15 16:03</i></dd>
     *
     * @param string 被签名字符串
     * @return java.lang.String
     * @since jdk1.7+
     */
    public static String md5Sign(String string) {
        try {
            MessageDigest md5 = MessageDigest.getInstance("MD5");
            md5.update(string.getBytes());
            return StringUtils.toHex(md5.digest());
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * <dt>Description:underlineToHump</dt>
     * <dd>下划线转驼峰法</dd>
     * <dd>author: wnfbx@163.com</dd>
     * <dd>version:1.0 <i>2022/1/15 16:07</i></dd>
     *
     * @param string    带下划线的字符串
     * @param smallHump true 为小驼峰，false 为大驼峰
     * @return java.lang.String
     * @since jdk1.7+
     */
    public static String underlineToHump(String string, boolean smallHump) {
        if (null == string) {
            return null;
        }
        if (isBlank(string)) {
            return "";
        }
        StringBuilder result = new StringBuilder();
        if (!string.contains("_")) {
            result.append(string);
        } else {
            String a[] = string.split("_");
            for (String s : a) {
                result.append(capitalize(s));
            }
        }
        return smallHump ? uncapitalize(result.toString()) : result.toString();
    }

    /**
     * <dt>Description:underlineToHump</dt>
     * <dd>下划线转小驼峰法</dd>
     * <dd>author: wnfbx@163.com</dd>
     * <dd>version:1.0 <i>2022/1/15 16:11</i></dd>
     *
     * @param string 带下划线的字符串
     * @return java.lang.String
     * @since jdk1.7+
     */
    public static String underlineToSmallHump(String string) {
        return underlineToHump(string, true);
    }

    /**
     * <dt>Description:humpToUnderline</dt>
     * <dd>驼峰法转下划线</dd>
     * <dd>author: wnfbx@163.com</dd>
     * <dd>version:1.0 <i>2022/1/15 16:11</i></dd>
     *
     * @param string    带大写的字符串
     * @param smallHump true 为小驼峰，false 为大驼峰
     * @return java.lang.String
     * @since jdk1.7+
     */
    public static String humpToUnderline(String string, boolean smallHump) {
        if (isBlank(string)) {
            return "";
        }
        StringBuffer sb = new StringBuffer();
        Pattern pattern = Pattern.compile("([A-Z]+)([a-z\\d]+)?");
        Matcher matcher = pattern.matcher(string);
        while (matcher.find()) {
            String group = matcher.group();
            sb.append(uncapitalize(group));
            sb.append(matcher.end() == string.length() ? "" : "_");
        }
        return smallHump ? sb.toString() : capitalize(sb.toString());
    }

    /**
     * <dt>Description:humpToUnderline</dt>
     * <dd>驼峰法转下划线</dd>
     * <dd>author: wnfbx@163.com</dd>
     * <dd>version:1.0 <i>2022/1/15 16:14</i></dd>
     *
     * @param string 字符串
     * @return java.lang.String
     * @since jdk1.7+
     */
    public static String humpToUnderline(String string) {
        return humpToUnderline(string, true);
    }

    /* bate================================================== */
    // public static String filterString(String sourceStr, String keywordsPath) {
    // return filterString(sourceStr, "*", keywordsPath);
    // }
    //
    // public static String filterString(String sourceStr, String replaceStr, String keywordsPath) {
    // try {
    // String s1 = new String();
    // File file = new File(keywordsPath);
    // if (file.exists()) {
    // InputStreamReader isr = new InputStreamReader(new FileInputStream(file), "UTF-8");
    // BufferedReader br = new BufferedReader(isr);
    // String s;
    // while ((s = br.readLine()) != null) {
    // s1 = s1 + s + " ";
    // }
    // br.close();
    // isr.close();
    // }
    //
    // String[] keys = s1.split("\\s");
    // int kl = keys.length;
    // for (int i = 0; i < kl; i++)
    // if (!"".equals(keys[i])) {
    // sourceStr = sourceStr.replace(keys[i], replaceStr);
    // }
    // } catch (IOException e) {
    // e.printStackTrace();
    // }
    // return sourceStr;
    // }
    //
    // public static String replaceJstl(Map<String, Object> m, String html) {
    // String v = "";
    // Pattern p = Pattern.compile("\\$\\{(.*?)}");
    // Matcher ma = p.matcher(html);
    // while (ma.find()) {
    // Object object = m.get(ma.group(1));
    // if (object != null) {
    // if ((object instanceof Date))
    // v = DateUtil.dateToStr((Date) object, "yyyy-MM-dd HH:mm:ss");
    // else {
    // v = object.toString();
    // }
    // }
    // html = html.replace(ma.group(0), v);
    // }
    // return html;
    // }
    //
    // public static String toCharsetString(String s, String charset) {
    // StringBuffer sb = new StringBuffer();
    // for (int i = 0; i < s.length(); i++) {
    // char c = s.charAt(i);
    // if ((c >= 0) && (c <= 'ÿ')) {
    // sb.append(c);
    // } else {
    // byte[] b;
    // try {
    // b = Character.toString(c).getBytes(charset);
    // } catch (Exception ex) {
    // b = new byte[0];
    // }
    // for (int j = 0; j < b.length; j++) {
    // int k = b[j];
    // if (k < 0)
    // k += 256;
    // sb.append("%" + Integer.toHexString(k).toUpperCase());
    // }
    // }
    // }
    // return sb.toString();
    // }
    //
    // public static String toUtf8String(String s) {
    // return toCharsetString(s, "utf-8");
    // }
    //
    // public static String ToSBC(String input) {
    // char[] c = input.toCharArray();
    // for (int i = 0; i < c.length; i++) {
    // if (c[i] == ' ')
    // c[i] = ' ';
    // else if (c[i] < '') {
    // c[i] = ((char) (c[i] + 65248));
    // }
    // }
    //
    // return new String(c);
    // }
    //
    // public static String ToDBC(String input) {
    // char[] c = input.toCharArray();
    // for (int i = 0; i < c.length; i++) {
    // if (c[i] == ' ')
    // c[i] = ' ';
    // else if ((c[i] > 65280) && (c[i] < 65375)) {
    // c[i] = ((char) (c[i] - 65248));
    // }
    // }
    //
    // return new String(c);
    // }
    // /**
    // * 获取Cookie组合字符串的MD5码的字符串
    // *
    // * @param value
    // * @return
    // */
    //
    // public static String getMD5(String value) {
    // String result = null;
    // try {
    // byte[] valueByte = value.getBytes();
    // MessageDigest md = MessageDigest.getInstance("MD5");
    // md.update(valueByte);
    // result = toHex(md.digest());
    // } catch (NoSuchAlgorithmException e) {
    // e.printStackTrace();
    // }
    // return result;
    // }
    //
    // /**
    // * 将传递进来的字节数组转换成十六进制的字符串形式并返回
    // *
    // * @param buffer
    // * @return
    // */
    // private static String toHex(byte[] buffer) {
    // StringBuffer sb = new StringBuffer(buffer.length * 2);
    // for (int i = 0; i < buffer.length; i++) {
    // sb.append(Character.forDigit((buffer[i] & 0xf0) >> 4, 16));
    // sb.append(Character.forDigit(buffer[i] & 0x0f, 16));
    // }
    // return sb.toString();
    //
    // }
}